package com.pansoft.kline.util;

import android.content.Context;

import com.efounder.chat.http.JFCommonRequestManager;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.pansoft.kline.greendao.DaoSessionUtil;
import com.pansoft.kline.model.ConfigCoinBean;
import com.pansoft.kline.model.ConfigMarketBean;
import com.pansoft.kline.model.ConfigSiteBean;
import com.pansoft.kline.model.KLineModel;
import com.pansoft.kline.model.KModel;
import com.pansoft.kline.model.LineModel;
import com.pansoft.klinelib.model.HisData;
import com.pansoft.openplanet.R;
import com.pansoft.openplanet.manager.CurrencyAndBourseManager;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;

import static com.pansoft.openplanet.constant.MarketConstant.K_LINE_URL;

/**
 * 数据解析的示例，数据来自于R.raw.his_data的json
 * Created by guoziwei on 2017/11/23.
 */

public class KLineUtil {

    private Context mContext;

    private static SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss", Locale.getDefault());
    private static SimpleDateFormat sFormat1 = new SimpleDateFormat("HHmm", Locale.getDefault());
    private static SimpleDateFormat sFormat2 = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
    private static SimpleDateFormat sFormat3 = new SimpleDateFormat("yyyyMMddHHmm", Locale.getDefault());

    public KLineUtil(Context context) {
        this.mContext = context;
    }

    public static List<HisData> getHisData(Context context) {
        InputStream is = context.getResources().openRawResource(R.raw.his_data);
        Writer writer = new StringWriter();
        char[] buffer = new char[1024];
        try {
            Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            int n;
            while ((n = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, n);
            }
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String json = writer.toString();
        final List<KLineModel> list = new Gson().fromJson(json, new TypeToken<List<KLineModel>>() {
        }.getType());
        List<HisData> hisData = new ArrayList<>(100);
        for (KLineModel m : list) {
            HisData data = new HisData();
            data.setHigh(m.getHigh());
            data.setLow(m.getLow());
            data.setOpen(m.getOpen());
            data.setClose(m.getClose());
            data.setVol(m.getVol());
            try {
                data.setDate(sFormat.parse(m.getsDate()).getTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            hisData.add(data);
        }
        return hisData;
    }

    /**
     * 请求K线图接口数据
     * @param TAG tag
     * @param marketId 市场id， 如btc， eth等市场
     * @param type 类型，如1分钟，1小时，月等
     * @param since 现在的时间，有的不需要传, 不传参数写"".
     * @param version 默认为3
     * @param beforeTime 加载此时间之前的数据， 不传写""
     * @return LineModels
     */
    public void getKLineModel(String TAG, final String marketId, String type, String since, String version,
                             String beforeTime,
                             final OnGetHisDataListener onGetHisDataListener) {
        HashMap<String, String> params = new HashMap<>();
        params.put("market_id", marketId);
        params.put("type", type);
        if (!"".equals(beforeTime)) {
            params.put("before", beforeTime);
        }
        params.put("version", version);
        JFCommonRequestManager.getInstance(mContext).requestGetByAsyn(TAG, K_LINE_URL, params, new JFCommonRequestManager.ReqCallBack<String>() {
            @Override
            public void onReqSuccess(String result) {
                try {
                    JSONObject jsonObject = new JSONObject(result);
                    List<KModel> list = new ArrayList<>();
                    if (jsonObject.optInt("code") == 0) {
                        JSONArray jsonArray = jsonObject.optJSONObject("data").optJSONArray("list");
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONArray dataArray = jsonArray.optJSONArray(i);
                            KModel kModel = new KModel();
                            /*数组依次为时间，开，高，低，收，交易总量*/
                            kModel.setPrice_o(dataArray.optDouble(1));
                            kModel.setPrice_c(dataArray.optDouble(4));
                            kModel.setPrice_h(dataArray.optDouble(2));
                            kModel.setPrice_l(dataArray.optDouble(3));
                            kModel.setVolume(dataArray.optDouble(5));
                            kModel.setTime(dataArray.optLong(0));
                            list.add(kModel);
                        }

                        //解析成K线数据
                        if (onGetHisDataListener != null && list.size() > 0) {
                            onGetHisDataListener.onGetHisDataSuccess(parseKLineData(marketId, list));
                        } else if (onGetHisDataListener != null) {
                            //请求失败
                            onGetHisDataListener.onGetHisDataFail();
                        }

                    } else {
                        if (onGetHisDataListener != null) {
                            //请求失败
                            onGetHisDataListener.onGetHisDataFail();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    if (onGetHisDataListener != null) {
                        //请求失败
                        onGetHisDataListener.onGetHisDataFail();
                    }
                }
            }

            @Override
            public void onReqFailed(String errorMsg) {
                if (onGetHisDataListener != null){
                    //请求失败
                    onGetHisDataListener.onGetHisDataFail();
                }
            }
        });
    }

    public static List<HisData> get1Day(Context context) {
        InputStream is = context.getResources().openRawResource(R.raw.oneday);
        Writer writer = new StringWriter();
        char[] buffer = new char[1024];
        try {
            Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            int n;
            while ((n = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, n);
            }
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String json = writer.toString();
        final List<LineModel> list = new Gson().fromJson(json, new TypeToken<List<LineModel>>() {
        }.getType());
        List<HisData> hisData = new ArrayList<>(100);
        for (int i = 0; i < list.size(); i++) {
            LineModel m = list.get(i);
            HisData data = new HisData();
            data.setClose(m.getPrice());
            data.setVol(m.getVolume());
            data.setOpen(i == 0 ? 0 : list.get(i - 1).getPrice());
            try {
                data.setDate(sFormat1.parse(m.getTime()).getTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }
            hisData.add(data);
        }
        return hisData;
    }

    public static List<List<HisData>> get5Day(Context context) {
        InputStream is = context.getResources().openRawResource(R.raw.fiveday);
        Writer writer = new StringWriter();
        char[] buffer = new char[1024];
        try {
            Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            int n;
            while ((n = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, n);
            }
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String json = writer.toString();
        final List<LinkedHashMap<String, List<LineModel>>> list = new Gson().fromJson(json, new TypeToken<List<LinkedHashMap<String, List<LineModel>>>>() {
        }.getType());
        List<List<HisData>> fivedays = new ArrayList<>(5);

        for (int i = 0; i < list.size(); i++) {

            List<HisData> hisData = new ArrayList<>(100);
            List<LineModel> lineModels = list.get(i).values().iterator().next();
            String time = list.get(i).keySet().iterator().next();

            for (int j = 0; j < lineModels.size(); j++) {
                LineModel m = lineModels.get(j);
                HisData data = new HisData();
                data.setClose(m.getPrice());
                data.setVol(m.getVolume());
                data.setOpen(j == 0 ? 0 : lineModels.get(j - 1).getPrice());
                try {
                    data.setDate(sFormat3.parse(time + m.getTime()).getTime());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                hisData.add(data);
            }
            fivedays.add(hisData);
        }
        return fivedays;
    }

    public static List<HisData> getK(Context context, int day) {
        int res = R.raw.day_k;
        if (day == 7) {
            res = R.raw.week_k;
        } else if (day == 30) {
            res = R.raw.month_k;
        }
        InputStream is = context.getResources().openRawResource(res);
        Writer writer = new StringWriter();
        char[] buffer = new char[1024];
        try {
            Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            int n;
            while ((n = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, n);
            }
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String json = writer.toString();
//        final List<KModel> list = new Gson().fromJson(json, new TypeToken<List<KModel>>() {
//        }.getType());
        List<KModel> list = new ArrayList<>();
        try {
            JSONObject jsonObject = new JSONObject(json);
            JSONArray jsonArray = jsonObject.optJSONArray("data");
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONArray dataArray = jsonArray.optJSONArray(i);
                KModel kModel = new KModel();
                /*数组依次为时间，开，高，低，收，交易总量*/
                kModel.setPrice_o(dataArray.optDouble(1));
                kModel.setPrice_c(dataArray.optDouble(4));
                kModel.setPrice_h(dataArray.optDouble(2));
                kModel.setPrice_l(dataArray.optDouble(3));
                kModel.setVolume(dataArray.optDouble(5));
                kModel.setTime(dataArray.optLong(0));
                list.add(kModel);
            }

            List<HisData> hisData = new ArrayList<>(100);
            for (int i = 0; i < list.size(); i++) {
                KModel m = list.get(i);
                HisData data = new HisData();
                data.setClose(m.getPrice_c());
                data.setOpen(m.getPrice_o());
                data.setHigh(m.getPrice_h());
                data.setLow(m.getPrice_l());
                data.setVol(m.getVolume());
                data.setDate(m.getTime());
                hisData.add(data);
            }
            return hisData;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 将KModel数据封装成K线数据
     * @param list KModel数据
     * @return K线数据
     */
    private List<HisData> parseKLineData(String marketId, List<KModel> list) {
        List<HisData> hisData = new ArrayList<>(100);
        ConfigMarketBean marketBean = DaoSessionUtil.getInstance().getConfigMarketBeanDao().load(marketId);
        ConfigCoinBean coinBean = DaoSessionUtil.getInstance().getConfigCoinBeanDao().load(marketBean.getCoin());
        ConfigSiteBean siteBean = DaoSessionUtil.getInstance().getConfigSiteBeanDao().load(marketBean.getSite());

        String currency = marketBean.getCurrency();
        for (int i = 0; i < list.size(); i++) {
            KModel m = list.get(i);
            HisData data = new HisData();
            String currencyCode = CurrencyAndBourseManager.getCurrencyUnitCode();
            double close = MarketNumberUtils.getRealPrice(siteBean.getUniqueKey(), marketBean.getCurrency(), currencyCode, m.getPrice_c());
            double open = MarketNumberUtils.getRealPrice(siteBean.getUniqueKey(), marketBean.getCurrency(), currencyCode, m.getPrice_o());
            double high = MarketNumberUtils.getRealPrice(siteBean.getUniqueKey(), marketBean.getCurrency(), currencyCode, m.getPrice_h());
            double low = MarketNumberUtils.getRealPrice(siteBean.getUniqueKey(), marketBean.getCurrency(), currencyCode, m.getPrice_l());

            String h = BtcKanNumberFormatUtil.assignNumberFormat(high, 8, 7);
            String c = BtcKanNumberFormatUtil.assignNumberFormat(close, 8, 7);
            String o = BtcKanNumberFormatUtil.assignNumberFormat(open, 8, 7);
            String l = BtcKanNumberFormatUtil.assignNumberFormat(low, 8, 7);
            String v = BtcKanNumberFormatUtil.assignNumberFormat(m.getVolume(), 8, 7);

            data.setClose(Double.valueOf(c));
            data.setOpen(Double.valueOf(o));
            data.setHigh(Double.valueOf(h));
            data.setLow(Double.valueOf(l));
            data.setVol(Double.valueOf(v));
            data.setDate(m.getTime());

            hisData.add(data);
        }
        return hisData;
    }

    public interface OnGetHisDataListener {

        void onGetHisDataSuccess(List<HisData> list);

        void onGetHisDataFail();
    }


    /**
     * KLine行情价格数字处理
     *   unValue为整除数  出现除不尽会出现异常，只作为单位转换使用
     * @param price 价格
     * @param unitValue 转换为万元（除以10000）  1,100,1000,10000
     * @param point 控制小数点的方法（0.00）  取小数点的位数
     * @return
     */
    public static String conversion(String price, String unitValue, String point) {

        BigDecimal bigDecimal = new BigDecimal(price);
        // 转换为万元（除以10000）
        BigDecimal decimal = bigDecimal.divide(new BigDecimal(unitValue));
        // 保留两位小数
        DecimalFormat formater = new DecimalFormat(point);
        // 四舍五入
        formater.setRoundingMode(RoundingMode.HALF_UP);    // 5000008.89
//        formater.setRoundingMode(RoundingMode.HALF_DOWN);// 5000008.89
//        formater.setRoundingMode(RoundingMode.HALF_EVEN);
        // 格式化完成之后得出结果
        return formater.format(decimal);

    }

    /**
     * 根据货币获取货币的单位
     * @param currency
     * @return
     */
    public static String getCurrencySymbol(String currency){

        if(currency.equals("CNY")){
            return "￥";
        }else if(currency.equals("USD")){
            return "$";
        }else if(currency.equals("KRW")){
            //朝鲜元  韩元
            return "₩";
        }else if(currency.equals("USDT")){
            //图格里克，蒙古的货币符号
            return "₮";
        }else if(currency.equals("JPY")){
            //日元
            return "￥";
        }else if(currency.equals("EUR")){
            //欧元
            return "€";
        }else if(currency.equals("GBP")){
            //英镑
            return "￡";
        }else if(currency.equals("BCH")){

            return "BCH";
        }else if(currency.equals("ETH")){
            return "E";
        }else if(currency.equals("AUD")){
            return "A$";
        }else if(currency.equals("BTC")){
            //泰铢
            return "฿";
        }else if(currency.equals("TRY")){
            //土耳其货币
            return "₤";
        }
        return "";
    }
}
